package com.cpit.qualitycontrol.web.controller;

import com.cpit.platform.common.constant.LogConstant;
import com.cpit.platform.common.entity.Result;
import com.cpit.platform.common.entity.TableDataQueryCondition;
import com.cpit.platform.common.entity.TableJsonData;
import com.cpit.platform.common.excel.ExportExcel;
import com.cpit.platform.common.excel.ImportExcel;
import com.cpit.platform.common.exception.CodeException;
import com.cpit.platform.common.utils.ExcelImportUtils;
import com.cpit.platform.common.utils.ResultUtil;
import com.cpit.platform.dao.OrganizationRepository;
import com.cpit.platform.dto.OperLog;
import com.cpit.platform.dto.Organization;
import com.cpit.platform.log.LogOperator;
import com.cpit.platform.security.service.UserInfo;
import com.cpit.platform.service.OperLogService;
import com.cpit.platform.service.OrganizationService;
import com.cpit.qualitycontrol.common.constant.LogConstantEx;
import com.cpit.qualitycontrol.entity.*;
import com.cpit.qualitycontrol.service.DeviceService;
import com.cpit.qualitycontrol.service.ProcessRuleService;
import com.cpit.qualitycontrol.service.WorkOrderService;
import com.cpit.qualitycontrol.service.WorkOrderTypeService;
import com.cpit.qualitycontrol.vo.ImportWorkOrderVo;
import com.cpit.qualitycontrol.vo.SubTaskCreateVo;
import com.cpit.qualitycontrol.vo.WorkOrderCreateVo;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.poi.ss.usermodel.Row;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by xxx on 2017/10/1.
 */
@Controller
@RequestMapping(value = "/workorder")
public class WorkOrderController {

    private final String loggerName = this.getClass().getName();

    @Autowired
    WorkOrderService workOrderService;

    @Autowired
    WorkOrderTypeService workOrderTypeService;

    @Autowired
    OrganizationService organizationService;

    @Autowired
    DeviceService deviceService;

    @Autowired
    OrganizationRepository organizationRepository;

    @Autowired
    ProcessRuleService processRuleService;

    @Autowired
    OperLogService operLogService;

    @ApiOperation(value = "创建工单", notes = "可批量创建，指定设备列表及一个或多个子任务")
    @ApiImplicitParam(name = "workOrderCreateVo", value = "工单创建VO", required = true, dataType = "WorkOrderCreateVo")
    @ResponseBody
    @PostMapping("/create")
    public Result createWorkOrder(@RequestBody WorkOrderCreateVo workOrderCreateVo) {
        OperLog operLog = new OperLog();
        operLog.setOperateTime(new Date());
        operLog.setOperateUser(getLoginUser().getUser().getUsername());
        operLog.setCommand(LogConstant.OPER_CREATE);
        operLog.setModule(LogConstantEx.MODULE_ASSIGNMENT);

        try {
            UserInfo userInfo = getLoginUser();

            LogOperator.debug(loggerName, "workOrderCreateVo = [" + workOrderCreateVo + "]");
            List<WorkOrder> workOrderList = workOrderService.createWorkOrder(userInfo.getUser().getId(), workOrderCreateVo);
            StringBuffer buffer = new StringBuffer();
            for (WorkOrder workOrder : workOrderList) {
                buffer.append(workOrder.getWorkOrderName());
                buffer.append("，");
            }
            buffer.deleteCharAt(buffer.length() - 1);
            operLog.setDetail("创建工单,工单名称：" + buffer.toString());
            operLog.setResult(Result.CODE_SUCCESS);
            operLogService.writeLog(operLog);
            return new Result<>(Result.CODE_SUCCESS, "", null);
        } catch (Exception e) {
            LogOperator.err(loggerName, "createWorkOrder error", e);
            operLog.setDetail("创建工单。失败原因：" + e.getMessage());
            operLog.setResult(Result.CODE_FAILED);
            operLogService.writeLog(operLog);
            return new Result<>(Result.CODE_FAILED, e.getMessage(), workOrderCreateVo);
        }
    }


    @ApiOperation(value = "查询待分派工单", notes = "通过条件查询待分派工单，返回List方式" +
            "支持模糊查询。")
    @ResponseBody
    @GetMapping("/queryNotAssignWorkOrder")
    public List<WorkOrder> queryNotAssignWorkOrderByUserId(
            @ApiParam(value = "当前页数， 以1开始。")
            @RequestParam(value = "page", required = false, defaultValue = "1") int page,
            @ApiParam(value = "当前页的内容长度。")
            @RequestParam(value = "size", required = false, defaultValue = "20") int size,
            @ApiParam(value = "排序方式：asc为升序，desc为降序。")
            @RequestParam(value = "order", required = false, defaultValue = "desc") String order,
            @ApiParam(value = "排序字段，与dto中声明的字段名称一致。")
            @RequestParam(value = "orderBy", required = false, defaultValue = "updateTime") String orderBy,
            @ApiParam(value = "产品线ID")
            @RequestParam(value = "productLineId", required = false) Long productLineId,
            @ApiParam(value = "项目名称，模糊搜索")
            @RequestParam(value = "projectName", required = false, defaultValue = "") String projectName,
            @ApiParam(value = "施工单位名称，模糊搜索")
            @RequestParam(value = "constructionTeamName", required = false, defaultValue = "") String constructionTeamName,
            @ApiParam(value = "设备ID，模糊搜索")
            @RequestParam(value = "deviceId", required = false, defaultValue = "") String deviceId,
            @ApiParam(value = "设备类型ID")
            @RequestParam(value = "deviceTypeId", required = false) Long deviceTypeId,
            @ApiParam(value = "工单状态")
            @RequestParam(value = "workOrderState", required = false) Integer workOrderState) {

        LogOperator.debug(loggerName, "page = [" + page + "], size = [" + size + "], order = [" + order
                + "], orderBy = [" + orderBy + "], productLineId = [" + productLineId + "], projectName = ["
                + projectName + "], constructionTeamName = [" + constructionTeamName + "], deviceName = ["
                + deviceId + "], deviceTypeId = [" + deviceTypeId + "], workOrderState = [" + workOrderState + "]");

        List<WorkOrder> workOrderList = workOrderService.queryNotAssignWorkOrderByUserId(getLoginUser().getUser().getId(), page, size, order, orderBy,
                productLineId, projectName, constructionTeamName, deviceId, deviceTypeId, workOrderState);

        return workOrderList;
    }

    @ApiOperation(value = "查询工单", notes = "通过条件查询工单，返回List方式" +
            "支持模糊查询。")
    @ResponseBody
    @GetMapping("/queryWorkOrder")
    public List<WorkOrder> queryWorkOrder(
            @ApiParam(value = "当前页数， 以1开始。")
            @RequestParam(value = "page", required = false, defaultValue = "1") int page,
            @ApiParam(value = "当前页的内容长度。")
            @RequestParam(value = "size", required = false, defaultValue = "20") int size,
            @ApiParam(value = "排序方式：asc为升序，desc为降序。")
            @RequestParam(value = "order", required = false, defaultValue = "desc") String order,
            @ApiParam(value = "排序字段，与dto中声明的字段名称一致。")
            @RequestParam(value = "orderBy", required = false, defaultValue = "updateTime") String orderBy,
            @ApiParam(value = "产品线ID")
            @RequestParam(value = "productLineId", required = false) Long productLineId,
            @ApiParam(value = "项目名称，模糊搜索")
            @RequestParam(value = "projectName", required = false, defaultValue = "") String projectName,
            @ApiParam(value = "施工单位名称，模糊搜索")
            @RequestParam(value = "constructionTeamName", required = false, defaultValue = "") String constructionTeamName,
            @ApiParam(value = "设备ID，模糊搜索")
            @RequestParam(value = "deviceId", required = false, defaultValue = "") String deviceId,
            @ApiParam(value = "设备类型ID")
            @RequestParam(value = "deviceTypeId", required = false) Long deviceTypeId,
            @ApiParam(value = "设备地址") @RequestParam(value = "addr", required = false) String addr,
            @ApiParam(value = "工单状态")
            @RequestParam(value = "workOrderState", required = false) Integer workOrderState) {

        LogOperator.debug(loggerName, "page = [" + page + "], size = [" + size + "], order = [" + order
                + "], orderBy = [" + orderBy + "], productLineId = [" + productLineId + "], projectName = ["
                + projectName + "], constructionTeamName = [" + constructionTeamName + "], deviceName = ["
                + deviceId + "], deviceTypeId = [" + deviceTypeId + "], workOrderState = [" + workOrderState + "]");

        List<WorkOrder> workOrderList = workOrderService.queryWorkOrder(getLoginUser().getUser().getId(), page, size, order, orderBy,
                productLineId, projectName, constructionTeamName, deviceId, deviceTypeId, workOrderState, addr);

        return workOrderList;
    }


    @SuppressWarnings("rawtypes")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cond", value = "JqGrid的条件对象，由JqGrid根据js参数自动封装。" +
                    "构造查询条件queryCond Map对象时，有选择条件的的参数key分别为productLineId, projectName, " +
                    "constructionTeamName, deviceName, deviceTypeId, workOrderState",
                    required = true, dataType = "TableDataQueryCondition")
    })
    @ResponseBody
    @RequestMapping(value = "/queryNotAssignWorkOrderJqg", method = RequestMethod.GET)
    public TableJsonData queryNotAssignWorkOrderJqg(TableDataQueryCondition cond) {

        LogOperator.debug(loggerName, "cond = [" + cond + "]");
        return this.workOrderService.findNotAssignWorkOrderByConditionJqg(getLoginUser().getUser().getId(), cond);
    }


    @SuppressWarnings("rawtypes")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cond", value = "JqGrid的条件对象，由JqGrid根据js参数自动封装。" +
                    "构造查询条件queryCond Map对象时，有选择条件的的参数key分别为productLineId, projectName, " +
                    "constructionTeamName, deviceName, deviceTypeId, workOrderState",
                    required = true, dataType = "TableDataQueryCondition")
    })
    @ResponseBody
    @RequestMapping(value = "/queryWorkOrderJqg", method = RequestMethod.GET)
    public TableJsonData queryWorkOrderJqg(TableDataQueryCondition cond) {

        LogOperator.debug(loggerName, "cond = [" + cond + "]");
        return this.workOrderService.findWorkOrderByConditionJqg(getLoginUser().getUser().getId(), cond, false);
    }

    private String getWholeTeamNames(String teamIds, Map<Integer, String> orgMap) {
        try {
            if (teamIds.indexOf(",") == -1) {
                return orgMap.get(Integer.parseInt(teamIds));
            } else {
                String[] ids = teamIds.split(",");
                StringBuffer nameBuf = new StringBuffer();
                for (String id : ids) {
                    if (nameBuf.length() > 0) {
                        nameBuf.append(",");
                    }
                    nameBuf.append(orgMap.get(Integer.parseInt(id)));
                }
                return nameBuf.toString();
            }
        } catch (NumberFormatException e) {
            return "";
        }
    }

    @ApiOperation(value = "批量派发工单", notes = "参数为工单IDS")
    @ResponseBody
    @PostMapping("/assignWorkOrders")
    public Result assignWorkOrders(
            @ApiParam(value = "工单ID数组", required = true)
            @RequestParam(required = true, value = "workOrderIds") List<Long> workOrderIds) {
        OperLog operLog = new OperLog();
        operLog.setOperateTime(new Date());
        operLog.setOperateUser(getLoginUser().getUser().getUsername());
        operLog.setCommand(LogConstant.OPER_MODIFY);
        operLog.setModule(LogConstantEx.MODULE_ASSIGNMENT);
        operLog.setDetail("派发工单,工单ID：" + workOrderIds);
        try {
            LogOperator.debug(loggerName, "workOrderIds = [" + workOrderIds + "]");
            workOrderService.assignWorkOrders(getLoginUser().getUser().getId(), workOrderIds);
            operLog.setResult(Result.CODE_SUCCESS);
            operLogService.writeLog(operLog);
            return new Result<>(Result.CODE_SUCCESS, "", null);
        } catch (Exception e) {
            LogOperator.err(loggerName, "createWorkOrder error", e);
            operLog.setDetail(operLog.getDetail() + "。失败原因：" + e.getMessage());
            operLog.setResult(Result.CODE_FAILED);
            operLogService.writeLog(operLog);
            return new Result<>(Result.CODE_FAILED, e.getMessage(), workOrderIds);
        }
    }


    @ApiOperation(value = "查询单个工单", notes = "参数为工单ID")
    @ResponseBody
    @GetMapping(value = "/{workOrderId}")
    public Result getWorkOrderById(@ApiParam(value = "工单ID", required = true)
                                   @PathVariable("workOrderId") Long workOrderId) {
        try {
            LogOperator.debug(loggerName, "workOrderId = [" + workOrderId + "]");
            WorkOrder workOrder = workOrderService.getWorkOrderById(workOrderId);
            Map<Integer, String> orgMap = getExportOrgMap();
            workOrder.setConstructionTeamNames(getWholeTeamNames(workOrder.getConstructionTeamIds(), orgMap));
            List<SubTask> subTaskList = workOrder.getSubTaskList();
            if (subTaskList != null && subTaskList.size() > 0) {
                for (SubTask subTask : subTaskList) {
                    subTask.setOrganizationTeamName(getWholeTeamNames(String.valueOf(subTask.getOrganizationTeamId()), orgMap));
                }
            }
            return new Result<>(Result.CODE_SUCCESS, "", workOrder);
        } catch (Exception e) {
            LogOperator.err(loggerName, "getSubTask error", e);
            return new Result<>(Result.CODE_FAILED, e.getMessage(), workOrderId);
        }
    }


    /**
     * 获取登录用户信息
     *
     * @return
     */
    private UserInfo getLoginUser() {
        UserInfo userDetails = (UserInfo) SecurityContextHolder.getContext()
                .getAuthentication()
                .getPrincipal();
        return userDetails;
    }


    @ApiOperation(value = "导入工单", notes = "向系统中导入工单")
    @ResponseBody
    @RequestMapping(value = "/importWorkOrder", method = RequestMethod.POST, consumes = "multipart/form-data")
    public Result<Integer> importWorkOrder(
            @ApiParam(value = "工单信息Excel表格。", required = true) @RequestParam("fileupload") MultipartFile file,
            HttpServletRequest request) {
        OperLog operLog = new OperLog();
        operLog.setOperateTime(new Date());
        operLog.setOperateUser(getLoginUser().getUser().getUsername());
        operLog.setCommand(LogConstant.OPER_IMPORT);
        operLog.setModule(LogConstantEx.MODULE_ASSIGNMENT);

        int headerNum = 0;
        int sheetIndex = 0;

        if (file == null) {
            throw new CodeException(Result.CODE_FAILED, "文件不能为空！");
        }
        String fileName = file.getOriginalFilename();

        operLog.setDetail("导入工单，文件名称：" + fileName);

        // 验证文件名是否合格
        if (!ExcelImportUtils.validateExcel(fileName)) {
            throw new CodeException(Result.CODE_FAILED, "文件必须是excel格式！");
        }
        long size = file.getSize();
        if (StringUtils.isEmpty(fileName) || size == 0) {
            throw new CodeException(Result.CODE_FAILED, "文件不能为空！");
        }

        //生成组织机构数据结构
        Map<String, Integer> orgNameIdMap = getImportOrgMap();

        // 创建导入Excel对象
        ImportExcel ei = null;

        List<ImportWorkOrderVo> importWorkOrderVoList = new ArrayList<>();
        StringBuilder errorSBAll = new StringBuilder();
        try {
            ei = new ImportExcel(file, headerNum, sheetIndex);

            for (int i = ei.getDataRowNum(), total = ei.getLastDataRowNum(); i < total; i++) {
                StringBuilder errorSBRow = new StringBuilder();
                int col = 4;
                Row row = ei.getRow(i);

                String productLineName = String.valueOf(ei.getCellValue(row, 0));
                String projectName = String.valueOf(ei.getCellValue(row, 1));
                String deviceTypeName = String.valueOf(ei.getCellValue(row, 2));
                String deviceId = String.valueOf(ei.getCellValue(row, 3));

                Device device = null;
                try {
                    device = deviceService.findById(deviceId);
                } catch (Exception e) {
                    LogOperator.err(loggerName, "Can not find the corresponding device:" + deviceId, e);
                }

                if (device == null) {
                    errorSBRow.append("根据设备编号查询不到对应的设备；");
                    errorSBAll.append("第 " + (i + 1) + " 行，").append(errorSBRow).append("\r\n");
                    continue;
                }
                if (!device.getProductLineName().equals(productLineName)) {
                    errorSBRow.append("产品线与设备信息不匹配；");
                    errorSBAll.append("第 " + (i + 1) + " 行，").append(errorSBRow).append("\r\n");
                    continue;
                }
                if (!device.getProjectName().equals(projectName)) {
                    errorSBRow.append("项目名称与设备信息不匹配；");
                    errorSBAll.append("第 " + (i + 1) + " 行，").append(errorSBRow).append("\r\n");
                    continue;
                }
                if (!device.getDeviceTypeName().equals(deviceTypeName)) {
                    errorSBRow.append("设备类型与设备信息不匹配；");
                    errorSBAll.append("第 " + (i + 1) + " 行，").append(errorSBRow).append("\r\n");
                    continue;
                }

                List<SubTaskCreateVo> subTaskCreateVoList = new ArrayList<>();
                while (true) {
                    SubTaskCreateVo subTaskCreateVo = new SubTaskCreateVo();

                    //工单类型
                    String workOrderTypeName = String.valueOf(ei.getCellValue(row, col++));

                    //施工单位
                    String organizationTeamName = String.valueOf(ei.getCellValue(row, col++));

                    //备注信息
                    String checkTask = String.valueOf(ei.getCellValue(row, col++));

                    //备注信息
                    String description = String.valueOf(ei.getCellValue(row, col++));

                    if (StringUtils.isEmpty(workOrderTypeName)
                            && StringUtils.isEmpty(organizationTeamName)
                            && StringUtils.isEmpty(checkTask)
                            && StringUtils.isEmpty(description)) {

                        //后面无子任务

                        break;
                    }

                    WorkOrderType workOrderType = null;
                    try {
                        workOrderType = workOrderTypeService.findByName(workOrderTypeName);
                    } catch (Exception e) {
                        LogOperator.err(loggerName, "Can not find the corresponding workOrder type:" + workOrderTypeName, e);
                    }

                    if (workOrderType == null) {
                        errorSBRow.append("查询不到对应的工单类型[ " + workOrderTypeName + " ]；");
                        break;
                    }

                    Integer organizationTeamId = orgNameIdMap.get(organizationTeamName);
                    if (organizationTeamId == null) {
                        errorSBRow.append("施工单位未找到[ " + organizationTeamName + " ]；");
                        break;
                    }

                    //判断子任务是否有流程规则
                    ProcessRule processRule = null;
                    try {
                        processRule = processRuleService.findByProcessRuleByDeviceTypeOrderTypeProject(
                                device.getDeviceTypeId(), workOrderType.getId(), device.getProjectId());
                    } catch (Exception e) {
                        LogOperator.err(loggerName, "Can not find the corresponding processRule", e);
                    }

                    if (processRule == null) {
                        errorSBRow.append("工单中的子任务未查询到对应的流程规则；");
                        break;
                    }
                    if (!("是".equals(checkTask) || "否".equals(checkTask))) {
                        errorSBRow.append("是否审核项填写错误；");
                        break;
                    }

                    subTaskCreateVo.setWorkOrderType(workOrderType.getId());
                    subTaskCreateVo.setOrganizationId(Long.valueOf(organizationTeamId));
                    subTaskCreateVo.setCheckTask(checkTask);
                    subTaskCreateVo.setDescription(description);

                    subTaskCreateVoList.add(subTaskCreateVo);

                } // while end

                if (errorSBRow.length() > 0) {
                    errorSBAll.append("第 " + (i + 1) + " 行，").append(errorSBRow).append("\r\n");
                } else {

                    //判断子任务工单类型是否重复
                    Set workOrderTypeSet = subTaskCreateVoList.stream().map(
                            subTaskCreateVo -> subTaskCreateVo.getWorkOrderType()).collect(Collectors.toSet());
                    if (workOrderTypeSet.size() != subTaskCreateVoList.size()) {
                        errorSBRow.append("子任务工单类型重复；");
                        errorSBAll.append("第 " + (i + 1) + " 行，").append(errorSBRow).append("\r\n");
                        continue;
                    }

                    ImportWorkOrderVo importWorkOrderVo = new ImportWorkOrderVo();
                    importWorkOrderVo.setDeviceId(deviceId);
                    importWorkOrderVo.setSubTaskCreateVoList(subTaskCreateVoList);

                    try {
                        workOrderService.createWorkOrderOneDevice(getLoginUser().getUser().getId(), subTaskCreateVoList, deviceId);
                        importWorkOrderVoList.add(importWorkOrderVo);
                    } catch (Exception e) {
                        LogOperator.err(loggerName, "import workOrder error", e);
                        errorSBAll.append("第 " + (i + 1) + " 行，").append(e.getMessage()).append("\r\n");
                    }
                }
            } // for end

//            if(importWorkOrderVoList.size()>0) {
//                workOrderService.createWorkOrderByExcel(getLoginUser().getUser().getId(), importWorkOrderVoList);
//            }

        } catch (Exception e) {
            LogOperator.err(loggerName, "import workOrder error", e);
            return ResultUtil.error(Result.CODE_FAILED, e.getMessage());
        }

        if (errorSBAll.length() > 0) {
            if (importWorkOrderVoList.size() == 0) {
                operLog.setResult(Result.CODE_FAILED);
                operLog.setDetail(operLog.getDetail() + "。失败原因：" + errorSBAll.toString());
                operLogService.writeLog(operLog);
                return ResultUtil.error(Result.CODE_FAILED, errorSBAll.toString());
            } else {
                operLog.setResult(Result.CODE_PARTIAL_SUCCESS);
                operLog.setDetail(operLog.getDetail() + "。失败原因：" + errorSBAll.toString());
                operLogService.writeLog(operLog);
                return ResultUtil.error(Result.CODE_PARTIAL_SUCCESS, errorSBAll.toString());
            }
        } else {
            LogOperator.debug(loggerName, importWorkOrderVoList.toString());
            operLog.setResult(Result.CODE_SUCCESS);
            operLogService.writeLog(operLog);
            return ResultUtil.success();
        }
    }

    @ApiOperation(value = "导出工单列表", notes = "将系统中的工单信息导出到excel文件。")
    @RequestMapping(value = {"/exportWorkOrder"}, method = RequestMethod.GET)
    public String exportWorkOrder(HttpServletRequest request, HttpServletResponse response,
                                  @ApiParam(value = "产品线ID")
                                  @RequestParam(value = "productLineId", required = false) Long productLineId,
                                  @ApiParam(value = "项目名称，模糊搜索")
                                  @RequestParam(value = "projectName", required = false, defaultValue = "") String projectName,
                                  @ApiParam(value = "施工单位名称，模糊搜索")
                                  @RequestParam(value = "constructionTeamName", required = false, defaultValue = "") String constructionTeamName,
                                  @ApiParam(value = "设备ID，模糊搜索")
                                  @RequestParam(value = "deviceId", required = false, defaultValue = "") String deviceId,
                                  @ApiParam(value = "设备类型ID")
                                  @RequestParam(value = "deviceTypeId", required = false) Long deviceTypeId,
                                  @ApiParam(value = "工单状态")
                                  @RequestParam(value = "workOrderState", required = false) Integer workOrderState) {

        OperLog operLog = new OperLog();
        operLog.setOperateTime(new Date());
        operLog.setOperateUser(getLoginUser().getUser().getUsername());
        operLog.setCommand(LogConstant.OPER_EXPORT);
        operLog.setModule(LogConstantEx.MODULE_ASSIGNMENT);

        String date = DateFormatUtils.format(new Date(), "yyyyMMddHHmmss");
        String fileName = "工单列表_" + date + ".xlsx";

        operLog.setDetail("导出工单，文件名称：" + fileName);

        Map<Integer, String> orgMap = getExportOrgMap();
        List<WorkOrder> workOrderList = workOrderService.queryWorkOrder(getLoginUser().getUser().getId(),
                productLineId, projectName, constructionTeamName, deviceId, deviceTypeId, workOrderState);

        String[] headers = {"产品线", "项目名称", "设备类型", "设备编号", "工单类型", "施工单位", "是否审核", "备注信息"};
        try {
            ExportExcel exportExcel = new ExportExcel(null, headers, "sheet1");

            for (WorkOrder workOrder : workOrderList) {
                int col = 0;
                Row row = exportExcel.addRow();
                exportExcel.addCell(row, col++, workOrder.getProductLineName());
                exportExcel.addCell(row, col++, workOrder.getProjectName());
                exportExcel.addCell(row, col++, workOrder.getDeviceTypeName());
                exportExcel.addCell(row, col++, workOrder.getDeviceId());
                //子任务列表
                List<SubTask> subTaskList = workOrder.getSubTaskList();
                if (subTaskList != null && subTaskList.size() > 0) {
                    for (SubTask subTask : subTaskList) {
                        exportExcel.addCell(row, col++, subTask.getWorkOrderTypeName());
                        exportExcel.addCell(row, col++, orgMap.get(subTask.getOrganizationTeamId().intValue()));
                        exportExcel.addCell(row, col++, subTask.getCheckTask());
                        exportExcel.addCell(row, col++, subTask.getDescription());
                    }
                }
            }

            exportExcel.write(request, response, fileName).dispose();

            operLog.setResult(Result.CODE_SUCCESS);
            operLogService.writeLog(operLog);

        } catch (IOException e) {
            LogOperator.err(loggerName, "export workorder info failed!", e);
            operLog.setResult(Result.CODE_FAILED);
            operLog.setDetail(operLog.getDetail() + "。失败原因：" + e.getMessage());
            operLogService.writeLog(operLog);
        }
        return null;
    }

    /**
     * 获取组织机构名称与ID 对应的Map
     *
     * @return
     */
    private Map<String, Integer> getImportOrgMap() {
        List<Organization> organizationList = organizationRepository.findAll();
        Map<String, Integer> orgNameIdMap = new HashMap();
        Map<Integer, Organization> orgIdOrgMap = new HashMap();
        for (Organization organization : organizationList) {
            orgIdOrgMap.put(organization.getId(), organization);
        }
        for (Organization organization : organizationList) {
            String name = organization.getName();
            Integer pId = organization.getParentId();
            while (pId != -1) {
                Organization orgParent = orgIdOrgMap.get(pId);
                name = orgParent.getName() + "/" + name;
                pId = orgParent.getParentId();
            }
            orgNameIdMap.put(name, organization.getId());
        }

        LogOperator.debug(loggerName, "map keys:" + orgIdOrgMap.entrySet());

        return orgNameIdMap;
    }

    /**
     * 获取组织机构与ID 与名称对应的Map
     *
     * @return
     */
    private Map<Integer, String> getExportOrgMap() {
        List<Organization> organizationList = organizationRepository.findAll();
        Map<Integer, String> orgIdNameMap = new HashMap();
        Map<Integer, Organization> orgIdOrgMap = new HashMap();
        for (Organization organization : organizationList) {
            orgIdOrgMap.put(organization.getId(), organization);
        }
        for (Organization organization : organizationList) {
            String name = organization.getName();
            Integer pId = organization.getParentId();
            while (pId != -1) {
                Organization orgParent = orgIdOrgMap.get(pId);
                name = orgParent.getName() + "/" + name;
                pId = orgParent.getParentId();
            }
            orgIdNameMap.put(organization.getId(), name);
        }

        LogOperator.debug(loggerName, "map keys:" + orgIdOrgMap.entrySet());

        return orgIdNameMap;
    }


}
